/*
 * Licensed to Nanjing RedOrange Co. ltd (RedOrange) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * RedOrange licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package redora.rdo.generator;

import java.io.File;
import java.util.Collection;

import org.apache.commons.io.FileUtils;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;

import redora.rdo.generator.exceptions.ModelGenerationException;

/**
 * Generates persistence sources and resources. If any XML schema is located in the
 * xsd directory, also the JAXB sources will be generated.
 * 
 * @goal generate
 * @phase generate-sources
 * @author jaap
 */
public class GenerateMojo extends AbstractMojo {
	
	/**
	 * The basePackage is always suffixed by this value. This will make all the
	 * projects using this library more easy to use because the persistence
	 * classes are all to be found under basePackage.PACKAGE_SUFFIX.
	 */
	public static final String PACKAGE_SUFFIX = "rdo";
	
	/**
	 * Location of the file.
	 * 
	 * @parameter expression="${project.build.directory}"
	 * @required
	 */
	private File buildDir;

	/**
	 * Package where the sources should be generated into.
	 * 
	 * @parameter expression=${persistulate.baseParameter}
	 *            default="${project.groupId}.${project.artifactId}"
	 * @required
	 */
	private String basePackage;
	
	/**
	 * @parameter expression="${project.artifactId}"
	 * @required
	 */
	private String artifactId;
	
	/**
	 * Default language of the project.
	 * 
	 * @parameter expression=${persistulate.baseParameter} default="en"
	 * @required
	 */
	private String defaultLanguage;

	/**
	 * Default base project for generating directory of the project.
	 * This is only used for this project itself (p-configuration).
	 * So, for example when you run the generator in a main project, but you actually want it to generate
	 * the sources in a sub project, you must use this.
	 * 
	 * @parameter expression=${persistulate.baseParameter} default=""
	 */
	private String baseProjectDir;

	/** src/main/resources/model/xsd */
	private File schemaDirectory;
	

	public void execute() throws MojoExecutionException {
		//Setting the directories
		String sourceDir = "src" + File.separator + "main" + File.separator
				+ "java";
		String resourceDir = "src" + File.separator + "main" + File.separator
				+ "resources";
		String modelDir = resourceDir + File.separator + "model";

		if (baseProjectDir != null && new File(baseProjectDir).isDirectory()) {
			getLog().info("Prefixed " + baseProjectDir + " as root");
			sourceDir = baseProjectDir + File.separator + sourceDir;
			resourceDir = baseProjectDir + File.separator + resourceDir;
			modelDir = baseProjectDir + File.separator + modelDir;
		}
		schemaDirectory = new File(modelDir + File.separator + "xsd");

		String jaxbPackage = basePackage + "." + PACKAGE_SUFFIX + ".model.xml";
		File generateDirectory = new File(buildDir + File.separator	+ "generated-sources");
		getLog().info("Generating sources for you now. I will use the following directories and settings");
		getLog().info("- Java source: " + sourceDir);
		getLog().info("- Generated java source " + generateDirectory.getPath());
		getLog().info("- Base package " + basePackage + "(." + PACKAGE_SUFFIX + ")");
		getLog().info("- XML Schemas location " + schemaDirectory.getPath());
		getLog().info("- JAXB package " + jaxbPackage);
		try {
			ModelProcessor
					.generate(basePackage + "." + PACKAGE_SUFFIX,
							defaultLanguage, sourceDir, buildDir.getPath(),
							resourceDir, artifactId);
			getLog().info("All model sources are generated");
			if (xml() != null && !xml().isEmpty()) {
				getLog().info("Found " + xml().size()
							+ " XML Schema(s), i will generate JAXB things for it (them)");
				JAXBGenerator jaxb = new JAXBGenerator(xml(), generateDirectory, jaxbPackage);
				jaxb.execute();
			} else
				getLog().info("Did not find any XSD to generate");
		} catch (ModelGenerationException e) {
			throw new MojoExecutionException(e.getMessage(), e);
		} catch (Exception e) {
			throw new MojoExecutionException("Ooops", e);
		}
	}

	/**
	 * Get xsd file list from schemaDirectory.
	 * 
	 * @return xml list
	 */
	@SuppressWarnings("unchecked")
	private Collection<File> xml() {
		if (schemaDirectory.exists()) {
			return FileUtils.listFiles(schemaDirectory, new String[]{"xsd"}, false);
		}
		return null;
	}
}
